package com.shopnight.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.google.gson.Gson;
import com.shopnight.constant.ShopIndentConstant;
import com.shopnight.entity.ErrandOrder;
import com.shopnight.service.ErrandOrderService;
import com.shopnight.service.ShopIndentService;
import com.shopnight.utils.WechatPay2ValidatorForRequest;
import com.shopnight.utils.WxMiniPayUtils;
import com.shopnight.utils.WxdecryptPayinformUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.mail.MessagingException;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadPoolExecutor;

@Slf4j
@RestController
@RequestMapping("/pay")
public class payController {

    @Autowired
    ShopIndentService shopIndentService;
    @Autowired
    ErrandOrderService errandOrderService;

    @Autowired
    private WxdecryptPayinformUtils wxdecryptPayinformUtils;

  @PostMapping("/callback")
  public String success(HttpServletRequest request, HttpServletResponse response) {

        Gson gson = new Gson();
        Map<String, String> map = new HashMap<>();

        try {
            String body = readData(request);
            Map<String, Object> bodyMap = gson.fromJson(body, HashMap.class);
            String requestId = (String) bodyMap.get("id");
//签名的验证
            //初始化verifier
            WxMiniPayUtils.initWXPayClient();
            WechatPay2ValidatorForRequest wechatPay2ValidatorForRequest
                    = new WechatPay2ValidatorForRequest(WxMiniPayUtils.verifier, requestId, body);
            if(!wechatPay2ValidatorForRequest.validate(request)){
                //失败应答
                response.setStatus(500);
                map.put("code", "ERROR");
                map.put("message", "通知验签失败");
                return gson.toJson(map);
            }

            //解密报文
            String plainText = wxdecryptPayinformUtils.decryptFromResource(bodyMap);
            //将明文转换成map
            Gson gsonDecrypt = new Gson();
            HashMap plainTextMap = gsonDecrypt.fromJson(plainText, HashMap.class);

            switch (Integer.valueOf((String) plainTextMap.get("attach")) ) {
                case 1:
                    // 处理零食订单
                    shopIndentService.processOrder(plainText);
                    break;
                case 2:
                    // 处理跑腿订单
                    errandOrderService.errandOrderCallback(plainText);
                    break;
                default:
                    break;
            }


            response.setStatus(200);
            //返回应答报文
            map.put("code", "SUCCESS");
            map.put("message", "成功");
            return gson.toJson(map);

        } catch (Exception e) {
            e.printStackTrace();
            //失败应答
            response.setStatus(500);
            //返回状态码
            map.put("code", "ERROR");
            //返回应答报文
            map.put("message", "失败");
            return gson.toJson(map);
        }

    }
  @RequestMapping("/refundWeChatNotify")
  public String refundWeChatNotify(HttpServletRequest request, HttpServletResponse response)  {
        Gson gson = new Gson();
        Map<String, String> map = new HashMap<>();
        try {
            String body = readData(request);
            Map<String, Object> bodyMap = gson.fromJson(body, HashMap.class);
           // log.error(body);
            String requestId = (String) bodyMap.get("id");
//签名的验证
            //初始化verifier
            WxMiniPayUtils.initWXPayClient();
            WechatPay2ValidatorForRequest wechatPay2ValidatorForRequest
                    = new WechatPay2ValidatorForRequest(WxMiniPayUtils.verifier, requestId, body);

            if(!wechatPay2ValidatorForRequest.validate(request)){
                log.error("通知验签失败");
                //失败应答
                response.setStatus(500);
                map.put("code", "ERROR");
                map.put("message", "通知验签失败");
                return gson.toJson(map);
            }

            //解密报文
            String plainText = wxdecryptPayinformUtils.decryptFromResource(bodyMap);
            //将明文转换成map
            Gson gsonDecrypt = new Gson();
            HashMap plainTextMap = gsonDecrypt.fromJson(plainText, HashMap.class);
            log.info("通知验签成功");
            ErrandOrder out_trade_no = errandOrderService.getOne(
                    new LambdaQueryWrapper<ErrandOrder>()
                            .eq(ErrandOrder::getCode, plainTextMap.get("out_trade_no").toString())
            );

            //更新状态
            if (out_trade_no != null){
                out_trade_no.setStatus(ShopIndentConstant.StatusEnum.refunded.getStatus());
                out_trade_no.setOutRefundNo( plainTextMap.get("out_refund_no").toString() );
                errandOrderService.updateById(out_trade_no);
            }

            //返回给微信
            response.setStatus(200);
            //返回应答报文
            map.put("code", "SUCCESS");
            map.put("message", "成功");
            return gson.toJson(map);

        }catch (Exception e){
            e.printStackTrace();
            //失败应答
            response.setStatus(500);
            //返回状态码
            map.put("code", "ERROR");
            //返回应答报文
            map.put("message", "失败");
            log.error("v3处理微信退款异步回调：错误-"+e.getMessage());
            return gson.toJson(map);
        }


    }


  private String  readData(HttpServletRequest request) throws IOException {
        ServletInputStream is = request.getInputStream();
        byte[] bs = new byte[1024];
        int len = -1;
        StringBuilder builder = new StringBuilder();
        while ((len = is.read(bs)) != -1){
            builder.append(new String(bs,0,len));
        }

        return builder.toString();
    }


}
